<?php
/**
 * Created by PhpStorm.
 * User: liuxiaojie
 * Date: 2019-03-27
 * Time: 14:19
 */

namespace app\tools;

use app\exception\CustomException;
use app\model\Customer;
use app\model\Goods;
use app\model\MoneyLog;
use app\model\MyCoupon;
use app\model\Order;
use app\model\RechargeOrder;
use app\model\RepairOrder;
use think\Db;

class Wxpay
{
    protected $appid;
    protected $mch_id;
    protected $key;
    protected $notify_url;

    function __construct()
    {
        $this->appid = config("mini.appid");
        $this->mch_id = config("mch_id");
        $this->key = config("api_key");
        $this->notify_url = "https://cat.legu17.com/api/wxpay/notify";
    }

    // 统一下单

    function unifieOrder($param = [], $notify_url = ''){

        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        $nonce_str = Helper::smsCode(32, 5);

        $post = [
            "appid"=> $this->appid,
            "mch_id"=> $this->mch_id,
            "nonce_str"=> $nonce_str,
            "body"=> '安吉虎猫-线上支付',
            "out_trade_no"=> $param['out_trade_no'],
            "total_fee"=> $param['total']*100,
            "spbill_create_ip"=> getIp(),
            "notify_url"=> $notify_url?:$this->notify_url,
            "trade_type"=> 'JSAPI',
            "openid"=> $param['openid'],
        ];

        $sign = $this->sign($post);
        $post['sign'] = $sign;

        $result =  Curl::curl($url, array2xml($post));

        $result = (array)simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA);
//        dump($result);
        if ((isset($result['return_code']) && $result['return_code'] == "FAIL" ) || (isset($result['result_code']) && $result['result_code'] == "FAIL"))
        {
            exit(fail("SERVER_INVALID"));
        }

        $result = [
            "appId"=> $this->appid,
            "timeStamp"=> strval(time()),
            "nonceStr"=> Helper::smsCode(32, 5),
            "package"=> "prepay_id={$result['prepay_id']}",
            "signType"=> "MD5",
        ];

        $result['paySign'] = $this->sign($result);

        unset($result['appid']);

        return $result;
    }

    function refund($param, $notify_url='')
    {
        $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        $nonce_str = Helper::smsCode(32, 5);
        $post = [
            "appid"=> $this->appid,
            "mch_id"=> $this->mch_id,
            "nonce_str"=> $nonce_str,
            "transaction_id"=> $param['transaction_id'],
            "out_refund_no"=> $param['out_refund_no'],
            "total_fee"=> $param['total_fee'],
            "refund_fee"=> $param['refund_fee'],
        ];

        $sign = $this->sign($post);
        $post['sign'] = $sign;
        $result = curl($url, array2xml($post), [], [
            'cert'=> ROOT_PATH.'sslpath/1528349611_20190313_cert/apiclient_cert.pem',
            'key'=> ROOT_PATH.'sslpath/1528349611_20190313_cert/apiclient_key.pem',
        ]);
        $result = (array)simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ((isset($result['return_code']) && $result['return_code'] == "FAIL" ) || (isset($result['result_code']) && $result['result_code'] == "FAIL"))
        {
            throw new CustomException();
        }
        return true;

    }

    // 回调

    function notify($param = [], $sign = '')
    {

        $sign_str = $this->sign($param);
        if($sign_str == $sign)
        {
            $data = RepairOrder::where([
                'serial_no'=> $param['out_trade_no']
            ])->field("pay_money, id, status, sheet_type, master_id, add_time, details, order_no")->find();

            if($data['pay_money'] * 100 == $param['total_fee'] && $data['status'] == 10)
            {
                Db::startTrans();

                try{
                    $update = [
                        "status"=> 20,
                        "trade_no"=> $param['transaction_id'],
                        "pay_time"=> date("Y-m-d H:i:s", strtotime($param['time_end']))
                    ];

                    RepairOrder::where(['id'=> $data['id']])->update($update);

                    Db::commit();
                    $wx = new Wx();
                    if($data['sheet_type'] == 1)
                    {
                        $unionid = db('customer')->where(['id'=> $data['master_id']])->value('unionid');
                        $openid = db('customer')->where(['unionid'=> $unionid, 'type'=> 2])->value('openid');
                        $wx->sendTemplate([
                            'openid'=> $openid,
                            'template_id'=> 'VkOPusrnpM5ueEl1WCcS9Pf7CBghPYMmWtkSrsCn9Ao',
                            'page'=> 'pages/repair/worker/order/order',
                            'data'=>[
                                "first"=> [
                                    "value"=> $data['details'],
                                ],
                                "keyword1"=> [
                                    "value"=> $data['order_no'],
                                ],
                                "keyword2"=> [
                                    "value"=> $data['add_time'],
                                ],
                            ]
                        ]);

                        db('repair_order')->where(['id'=> $data['id']])->update(['is_tui'=> 1]);
                    }

                    $wx->sendTemplate([
                        'openid'=> 'oVKH41ZAzmuGlUaJqY_S-VHrTsxA',
                        'template_id'=> 'VkOPusrnpM5ueEl1WCcS9Pf7CBghPYMmWtkSrsCn9Ao',
                        'page'=> '',
                        'data'=>[
                            "first"=> [
                                "value"=> $data['details'],
                            ],
                            "keyword1"=> [
                                "value"=> $data['order_no'],
                            ],
                            "keyword2"=> [
                                "value"=> $data['add_time'],
                            ],
                        ]
                    ]);

                    exit("<xml>
                          <return_code><![CDATA[SUCCESS]]></return_code>
                          <return_msg><![CDATA[OK]]></return_msg>
                        </xml>");

                }catch (\Exception $exception){
                    Db::rollback();
                }
            }
        }

    }

    function notify2($param = [], $sign = '')
    {

        $sign_str = $this->sign($param);
        if($sign_str == $sign)
        {
            $data = RechargeOrder::where([
                'serial_no'=> $param['out_trade_no']
            ])->field("price, id, status, customer_id, diam")->find();

            if($data['price'] * 100 == $param['total_fee'] && $data['status'] == 10)
            {
                Db::startTrans();

                try{
                    $update = [
                        "status"=> 20,
                        "trade_no"=> $param['transaction_id'],
                        "pay_time"=> date("Y-m-d H:i:s", strtotime($param['time_end']))
                    ];

                    RechargeOrder::where(['id'=> $data['id']])->update($update);
                    Customer::where(['id'=> $data['customer_id']])->setInc('diam', $data['diam']);

                    Db::commit();

                    exit("<xml>
                          <return_code><![CDATA[SUCCESS]]></return_code>
                          <return_msg><![CDATA[OK]]></return_msg>
                        </xml>");

                }catch (\Exception $exception){
                    Db::rollback();
                }
            }
        }

    }

    function notify3($param = [], $sign = '')
    {

        $sign_str = $this->sign($param);
        if($sign_str == $sign)
        {
            $sign_str = $this->sign($param);
            if($sign_str == $sign)
            {
                $data = Order::where([
                    'serial_no'=> $param['out_trade_no']
                ])->field("pay_money, id, status, type, coupon_id, uid, customer_id, num, add_money, add_tiger, goods_id, num, tiger_tee")->find();

                if($data['pay_money'] * 100 == $param['total_fee'] && $data['status'] == 10)
                {
                    Db::startTrans();

                    try{
                        if($data['type'] == 2)
                        {
                            $update = [
                                "status"=> 20,
                                "trade_no"=> $param['transaction_id'],
                                "pay_time"=> date("Y-m-d H:i:s", strtotime($param['time_end']))
                            ];

                            Order::where(['id'=> $data['id']])->update($update);
                        }else{
                            $update = [
                                "status"=> 20,
                                "trade_no"=> $param['transaction_id'],
                                "pay_time"=> date("Y-m-d H:i:s", strtotime($param['time_end']))
                            ];
                            Order::where(['id'=> $data['id']])->update($update);

                            $coupon_ids = explode(',', $data['coupon_id']);
                            $coupon = db('coupon')->where(['coupon_id'=> ['in', $coupon_ids]])->field('coupon_id, expired_type, expired_date, start_time, uid')->select();
                            $post = [];
                            foreach (range(1, $data['num']) as $value)
                            {
                                foreach ($coupon as $v)
                                {
                                    if($v['expired_type'] == 1){
                                        $start_time = $v['start_time'];
                                    }elseif($v['expired_type'] == 2){
                                        $start_time = date('Y-m-d');
                                    }
                                    $end_time = date('Y-m-d', strtotime($start_time) + 86400*$v['expired_date']);
                                    $post[] = [
                                        'coupon_id'=> $v['coupon_id'],
                                        'customer_id'=> $data['customer_id'],
                                        'status'=> 1,
                                        'start_time'=> $start_time,
                                        'end_time'=> $end_time,
                                        'uid'=> $v['uid'],
                                        'o_id'=> $data['id'],
                                    ];
                                }
                            }
                            $code = db('customer')->where(['id'=> $data['customer_id']])->value('code');
                            if($code)
                            {
                                Customer::where(['id'=> $data['customer_id']])->setInc('money', $data['add_money']);
                                Customer::where(['id'=> $data['customer_id']])->setInc('tiger_tee', $data['add_tiger']);

                                if($data['add_money']>0 || $data['add_tiger']>0){
                                    $unionid = db('customer')->where(['id'=> $data['customer_id']])->value('unionid');
                                    $openid = db('customer')->where(['unionid'=> $unionid, 'type'=> 2])->value('openid');
                                    $wx = new Wx();
                                    if($data['add_money']>0 && $data['add_tiger']<=0)
                                    {
                                        MoneyLog::addLog([
                                            "child_id"=> 0,
                                            "u_id"=> $data['customer_id'],
                                            "type"=> 1,
                                            "value"=> $data['add_money'],
                                            "reason_type"=> 13
                                        ]);
                                        $value = "恭喜您获得{$data['add_money']}元现金！！！";
                                    }elseif ($data['add_tiger']>0 && $data['add_money']<=0){
                                        MoneyLog::addLog([
                                            "child_id"=> 0,
                                            "u_id"=> $data['customer_id'],
                                            "type"=> 2,
                                            "value"=> $data['add_tiger'],
                                            "reason_type"=> 14
                                        ]);
                                        $value = "恭喜您获得{$data['tiger_tee']}虎牙！！！";
                                    }elseif ($data['add_money']>0 && $data['add_tiger']>0){
                                        MoneyLog::addLog([
                                            "child_id"=> 0,
                                            "u_id"=> $data['customer_id'],
                                            "type"=> 1,
                                            "value"=> $data['add_money'],
                                            "reason_type"=> 13
                                        ]);
                                        MoneyLog::addLog([
                                            "child_id"=> 0,
                                            "u_id"=> $data['customer_id'],
                                            "type"=> 2,
                                            "value"=> $data['add_tiger'],
                                            "reason_type"=> 14
                                        ]);
                                        $value = "恭喜您获得{$data['add_money']}元现金和{$data['add_tiger']}虎牙！！！";
                                    }
                                    $wx->sendTemplate([
                                        'openid'=> $openid,
                                        'template_id'=> 'KO7PzleBytwcD9tQ5bGixBdI7ewiSXIf_lM9az1JFWc',
                                        'page'=> 'pages/mine/mine',
                                        'data'=>[
                                            "first"=> [
                                                "value"=> "您有收益到账了！！！",
                                            ],
                                            "keyword1"=> [
                                                "value"=> $value,
                                            ],
                                            "keyword2"=> [
                                                "value"=> date('Y-m-d H:i:s'),
                                            ],
                                        ]
                                    ]);
                                }
                            }else{
                                $parent_id = db('master_log')->where(['u_id'=> $data['customer_id']])->value('parent_id');
                                if($parent_id)
                                {
                                    Customer::where(['id'=> $parent_id])->setInc('money', $data['add_money']);
                                    Customer::where(['id'=> $parent_id])->setInc('tiger_tee', $data['add_tiger']);

                                    if($data['add_money']>0 || $data['add_tiger']>0){
                                        $unionid = db('customer')->where(['id'=> $parent_id])->value('unionid');
                                        $openid = db('customer')->where(['unionid'=> $unionid, 'type'=> 2])->value('openid');
                                        $wx = new Wx();
                                        if($data['add_money']>0 && $data['add_tiger']<=0)
                                        {
                                            MoneyLog::addLog([
                                                "child_id"=> 0,
                                                "u_id"=> $data['customer_id'],
                                                "type"=> 1,
                                                "value"=> $data['add_money'],
                                                "reason_type"=> 13
                                            ]);
                                            $value = "恭喜您获得{$data['add_money']}元现金！！！";
                                        }elseif ($data['add_tiger']>0 && $data['add_money']<=0){
                                            MoneyLog::addLog([
                                                "child_id"=> 0,
                                                "u_id"=> $data['customer_id'],
                                                "type"=> 2,
                                                "value"=> $data['add_tiger'],
                                                "reason_type"=> 14
                                            ]);
                                            $value = "恭喜您获得{$data['tiger_tee']}虎牙！！！";
                                        }elseif ($data['add_money']>0 && $data['add_tiger']>0){
                                            MoneyLog::addLog([
                                                "child_id"=> 0,
                                                "u_id"=> $data['customer_id'],
                                                "type"=> 1,
                                                "value"=> $data['add_money'],
                                                "reason_type"=> 13
                                            ]);
                                            MoneyLog::addLog([
                                                "child_id"=> 0,
                                                "u_id"=> $data['customer_id'],
                                                "type"=> 2,
                                                "value"=> $data['add_tiger'],
                                                "reason_type"=> 14
                                            ]);
                                            $value = "恭喜您获得{$data['add_money']}元现金和{$data['add_tiger']}虎牙！！！";
                                        }
                                        $wx->sendTemplate([
                                            'openid'=> $openid,
                                            'template_id'=> 'KO7PzleBytwcD9tQ5bGixBdI7ewiSXIf_lM9az1JFWc',
                                            'page'=> 'pages/mine/mine',
                                            'data'=>[
                                                "first"=> [
                                                    "value"=> "您有收益到账了！！！",
                                                ],
                                                "keyword1"=> [
                                                    "value"=> $value,
                                                ],
                                                "keyword2"=> [
                                                    "value"=> date('Y-m-d H:i:s'),
                                                ],
                                            ]
                                        ]);
                                    }
                                }
                            }

                            MyCoupon::insertAll($post);

                        }

                        Goods::where(['goods_id'=> $data['goods_id']])->setDec('num', $data['num']);
                        Goods::where(['goods_id'=> $data['goods_id']])->setInc('sale_num', $data['num']);
                        Customer::where(['id'=> $data['customer_id'], 'tiger_tee'=>['>=', $data['tiger_tee']]])->setDec('tiger_tee', $data['tiger_tee']);

                        Db::commit();

                        exit("<xml>
                          <return_code><![CDATA[SUCCESS]]></return_code>
                          <return_msg><![CDATA[OK]]></return_msg>
                        </xml>");

                    }catch (\Exception $exception){
//                        echo $exception->getMessage();
                        Db::rollback();
                    }
                }
            }
        }

    }

    // 签名
    function sign($param){

        ksort($param);

        $str = "";

        foreach ($param as $k=> $v){
            if($v){
                $str .= $k."=".$v."&";
            }
        }

        $stringSignTemp = $str."key=".$this->key;
        $sign_value = strtoupper(md5($stringSignTemp));

        return $sign_value;

    }

}